<template>
  <div style="text-align: left">
    <el-row>
      <el-col :span="6">
        <el-row>
          <el-card
            shadow="never"
            style="margin-top: -20px;margin-left: -20px"
          >
            <div slot="header" class="clearfix">
              <span>菜单信息</span>
              <el-button
                :loading="loading"
                type="text"
                style="float: right;color: white"
                circle
                size="mini"
                icon="el-icon-refresh-right"
                @click="getMenuTree"
              />
              <BeeButton
                code="menuAdd"
                type="text"
                style="float: right;color: white"
                circle
                size="mini"
                icon="el-icon-plus"
                @click="append('')"
              />
            </div>
            <div v-loading="loading">
              <el-input
                v-model="filterText"
                placeholder="输入关键字进行过滤"
                size="small"
              />
              <el-tree
                ref="tree"
                :filter-node-method="filterNode"
                default-expand-all
                style="overflow: auto;height: 100%;width: 100%"
                :data="menuTrees"
                :props="defaultProps"
                :expand-on-click-node="false"
              >
                <span slot-scope="{ node, data }" class="custom-tree-node" @click="handleNodeClick(data.id)">
                  <span>{{ node.label }}</span>
                  <span>
                    <BeeButton
                      v-show="data.type==='0'"
                      code="menuAdd"
                      type="text"
                      size="mini"
                      @click.stop="append(data)"
                    >新增
                    </BeeButton>
                    <BeeButton
                      v-show="data.children===null"
                      code="menuDelete"
                      type="text"
                      size="mini"
                      @click.stop="remove(data.id,'菜单删除')"
                    >
                      删除
                    </BeeButton>
                  </span>
                </span>
              </el-tree>
            </div>
          </el-card>
        </el-row>
      </el-col>
      <el-col :span="18">
        <el-card

          shadow="never"
          style="margin-top: -20px;margin-right: -20px;margin-left: 10px"
        >
          <div slot="header" class="clearfix">
            <span>菜单详情</span>
            <el-button
              type="text"
              style="float: right;color: white"
              circle
              size="mini"
              icon="el-icon-refresh-right"
              :loading="menuTableLoading"
              @click="getMenuButton(nowMenuID)"
            />

            <el-button
              type="text"
              style="float: right;color: white"
              circle
              size="mini"
              icon="el-icon-edit"
              @click="editFlagChange"
            />
            <el-button
              type="text"
              :loading="menuLoading"
              style="float: right;color: white"
              circle
              size="mini"
              icon="el-icon-check"
              @click="saveMenuDtail"
            />
          </div>
          <div v-loading="menuTableLoading">
            <el-form
              ref="editMenuDetail"
              :model="menuDetailData"
              :rules="rulesEditMenuDetail"
              label-position="left"
              inline
              class="table-expand"
            >
              <el-form-item label="菜单名称" prop="name">
                <span v-show="!editFlag">{{ menuDetailData.name }}</span>
                <el-input
                  v-show="editFlag"
                  v-model="menuDetailData.name"
                  :maxlength="10"
                  show-word-limit
                  size="mini"
                  placeholder="请输入菜单名称"
                  clearable
                  :style="{width: '100%'}"
                />
              </el-form-item>
              <el-form-item label="菜单路径" prop="path">
                <span v-show="!editFlag">{{ menuDetailData.path }}</span>
                <el-input
                  v-show="editFlag"
                  v-model="menuDetailData.path"
                  :maxlength="20"
                  show-word-limit
                  size="mini"
                  placeholder="请输入菜单路径"
                  clearable
                  :style="{width: '100%'}"
                />
              </el-form-item>
              <el-form-item label="组件名称" prop="component">
                <span v-show="!editFlag">{{ menuDetailData.component }}</span>
                <el-input
                  v-show="editFlag"
                  v-model="menuDetailData.component"
                  :maxlength="20"
                  show-word-limit
                  size="mini"
                  placeholder="请输入组件名称"
                  clearable
                  :style="{width: '100%'}"
                />
              </el-form-item>
              <el-form-item label="类型">
                <span>{{ menuTypeDict(menuDetailData.type) }}</span>
              </el-form-item>
              <el-form-item label="图标" prop="icon">
                <i v-show="!editFlag" :class="menuDetailData.icon" />
                <e-icon-picker v-show="editFlag" v-model="menuDetailData.icon" />
              </el-form-item>
              <el-form-item label="排序" prop="orderNum">
                <span v-show="!editFlag">{{ menuDetailData.orderNum }}</span>
                <el-input-number
                  v-show="editFlag"
                  v-model="menuDetailData.orderNum"
                  placeholder="请输入排序"
                  :step="1"
                />
              </el-form-item>
              <el-form-item label="备注" style="width: 100%">
                <span v-show="!editFlag">{{ menuDetailData.remark }}</span>
                <el-input
                  v-show="editFlag"
                  v-model="menuDetailData.remark"
                  type="textarea"
                  placeholder="请输入备注"
                  :maxlength="255"
                  show-word-limit
                  :autosize="{minRows: 2, maxRows: 4}"
                  style="width: 100%"
                />
              </el-form-item>
            </el-form>
            <div v-show="menuDetailData.type!=='0'">
              <el-divider>
                <BeeButton
                  code="menuButtonSearch"
                  type="text"
                  icon="el-icon-search"
                  size="mini"
                  @click="searchFlagChange"
                />
                <span style="margin: 40px">按钮</span>
                <BeeButton
                  code="menuButtonAdd"
                  type="text"
                  size="mini"
                  icon="el-icon-plus"
                  @click="addButton"
                />
              </el-divider>
              <el-row v-show="searchFlag" :gutter="15">
                <el-form
                  ref="searchForm"
                  :model="searchFormData"
                  :rules="rules"
                  size="medium"
                  label-width="100px"
                  label-position="left"
                >
                  <el-col :span="9">
                    <el-form-item label="名称" prop="name">
                      <el-input v-model="searchFormData.name" placeholder="请输入按钮名称" clearable :style="{width: '100%'}" />
                    </el-form-item>
                  </el-col>
                  <el-col :span="9">
                    <el-form-item label="权限码" prop="buttonCode">
                      <el-input v-model="searchFormData.buttonCode" placeholder="请输入按钮权限码" clearable :style="{width: '100%'}" />
                    </el-form-item>
                  </el-col>
                  <el-col :span="4">
                    <el-form-item size="mini">
                      <BeeButton code="menuButtonSearch" type="primary" @click="getMenuButton(nowMenuID)">查询</BeeButton>
                    </el-form-item>
                  </el-col>
                </el-form>
              </el-row>
              <div v-if="tableData.length>0">
                <el-table
                  :size="isMobile()?'mini':'medium'"
                  :data="tableData"
                  style="width: 100%;min-height: 350px"
                  border
                  tooltip-effect="light"
                >
                  <el-table-column
                    prop="name"
                    label="按钮名称"
                  />
                  <el-table-column
                    prop="buttonCode"
                    label="按钮权限码"
                  />
                  <el-table-column
                    prop="remark"
                    label="备注"
                  />
                  <el-table-column
                    prop="id"
                    fixed="right"
                    label="操作"
                    width="80px"
                  >
                    <template slot-scope="scope">
                      <BeeButton
                        code="menuButtonDelete"
                        size="mini"
                        type="danger"
                        @click="remove(scope.row.id,'按钮删除')"
                      >删除
                      </BeeButton>
                    </template>
                  </el-table-column>
                </el-table>
                <el-pagination
                  :page-size="size"
                  :current-page="current"
                  layout="total,sizes, prev, pager, next,jumper"
                  :total="total"
                  :page-sizes="[ 2,3,5]"
                  @size-change="handleSizeChange"
                  @current-change="handleCurrentChange"
                />
              </div>
              <el-empty v-else description="查询结果为空" />
            </div>
          </div>

        </el-card>
      </el-col>
    </el-row>
    <!--菜单新增弹出框-->
    <el-dialog
      :title="dialogTitle"
      :visible.sync="showDialog"
      :close-on-click-modal="false"
      z-index="99"
      :width="isMobile()?'100%':'50%'"
      @close="close()"
    >
      <el-row :gutter="15">
        <el-form
          ref="editOrAddForm"
          :model="addOrEditFormData"
          :rules="rulesEditOrAdd"
          size="medium"
          label-width="100px"
          label-position="left"
        >
          <el-col :span="12">
            <el-form-item label="菜单名称" prop="name">
              <el-input
                v-model="addOrEditFormData.name"
                placeholder="请输入菜单名称"
                :maxlength="10"
                show-word-limit
                clearable
                :style="{width: '100%'}"
              />
            </el-form-item>
          </el-col>
          <el-col :span="12">
            <el-form-item label="菜单路径" prop="path">
              <el-input
                v-model="addOrEditFormData.path"
                :maxlength="20"
                show-word-limit
                placeholder="请输入菜单路径"
                clearable
                :style="{width: '100%'}"
              />
            </el-form-item>
          </el-col>
          <el-col :span="12">
            <el-form-item label="组件名称" prop="component">
              <el-input
                v-model="addOrEditFormData.component"
                :maxlength="20"
                show-word-limit
                placeholder="请输入组件名称"
                clearable
                :style="{width: '100%'}"
              />
            </el-form-item>
          </el-col>
          <el-col :span="12">
            <el-form-item label="类型">
              <span>{{ menuTypeDict(addOrEditFormData.type) }}</span>
              <el-select v-model="addOrEditFormData.type" placeholder="请选择类型" clearable :style="{width: '100%'}">
                <el-option
                  v-for="(item, index) in typeOptions"
                  :key="index"
                  :label="item.label"
                  :value="item.value"
                />
              </el-select>
            </el-form-item>
          </el-col>
          <el-col :span="12">
            <el-form-item label="图标" prop="icon">
              <e-icon-picker v-model="addOrEditFormData.icon" />
            </el-form-item>
          </el-col>
          <el-col :span="12">
            <el-form-item label="排序" prop="orderNum">
              <el-input-number v-model="addOrEditFormData.orderNum" style="width: 100%" placeholder="请输入排序" :step="1" />
            </el-form-item>
          </el-col>
          <el-col :span="24">
            <el-form-item label="备注">
              <el-input
                v-model="addOrEditFormData.remark"
                type="textarea"
                placeholder="请输入备注"
                :maxlength="255"
                show-word-limit
                :autosize="{minRows: 2, maxRows: 4}"
                :style="{width: '100%'}"
              />
            </el-form-item>
          </el-col>
        </el-form>
      </el-row>
      <div slot="footer">
        <el-button @click="close()">关闭</el-button>
        <el-button :loading="buttonLoading" type="primary" @click="handelConfirm">确定</el-button>
      </div>
    </el-dialog>
    <!--按钮新增弹出框-->
    <el-dialog
      title="新增按钮"
      :visible.sync="showButtonDialog"
      :close-on-click-modal="false"
      :width="isMobile()?'100%':'30%'"
      z-index="99"
      @close="buttonClose()"
    >
      <el-row :gutter="15">
        <el-form
          ref="addButtonFormData"
          :model="addButtonFormData"
          :rules="rulesAddButton"
          size="medium"
          label-width="100px"
          label-position="left"
        >
          <el-col :span="24">
            <el-form-item label="按钮名称" prop="name">
              <el-input
                v-model="addButtonFormData.name"
                :maxlength="10"
                show-word-limit
                placeholder="请输入菜单名称"
                clearable
                :style="{width: '100%'}"
              />
            </el-form-item>
          </el-col>
          <el-col :span="24">
            <el-form-item label="按钮权限码" prop="buttonCode">
              <el-input
                v-model="addButtonFormData.buttonCode"
                placeholder="请输入按钮权限码"
                :maxlength="30"
                show-word-limit
                clearable
                :style="{width: '100%'}"
              />
            </el-form-item>
          </el-col>
          <el-col :span="24">
            <el-form-item style="width: 100%" label="备注">
              <el-input
                v-model="addButtonFormData.remark"
                type="textarea"
                placeholder="请输入备注"
                :maxlength="255"
                show-word-limit
                :autosize="{minRows: 2, maxRows: 4}"
                :style="{width: '100%'}"
              />
            </el-form-item>
          </el-col>
        </el-form>
      </el-row>
      <div slot="footer">
        <el-button @click="buttonClose()">关闭</el-button>
        <el-button :loading="buttonLoading" type="primary" @click="buttonHandelConfirm">确定</el-button>
      </div>
    </el-dialog>
  </div>
</template>

<script>
import { addMenu, deleteById, editMenu, getById, getMenuTree, page } from '@/api/menu'
import { menuTypeDict } from '@/utils/ParamFilter'
import { MessageBox } from 'element-ui'
import BeeButton from '@/components/RoleButton/index.vue'
import { isMobile } from '@/utils/ObjectUtil'
export default {
  name: 'Menu',
  components: { BeeButton },
  data() {
    return {
      menuTrees: [],
      filterText: '',
      menuLoading: false,
      menuTableLoading: false,
      buttonLoading: false,
      loading: false,
      editFlag: false,
      showDialog: false,
      showButtonDialog: false,
      dialogTitle: undefined,
      tableData: [],
      nowMenuID: undefined,
      current: 0,
      size: 5,
      total: 0,
      flagChange: 0,
      isChange: false,
      searchFormData: {
        name: undefined,
        buttonCode: undefined
      },
      searchFlag: !isMobile(),
      menuDetailData: {
        name: undefined,
        path: undefined,
        component: undefined,
        type: undefined,
        icon: undefined,
        orderNum: 0,
        remark: undefined
      },
      addOrEditFormData: {
        parentId: undefined,
        name: undefined,
        path: undefined,
        component: undefined,
        type: undefined,
        icon: undefined,
        orderNum: 0,
        remark: undefined
      },
      addButtonFormData: {
        name: undefined,
        remark: undefined,
        buttonCode: undefined,
        parentId: undefined
      },
      defaultProps: {
        children: 'children',
        label: 'name'
      },
      typeOptions: [{
        'label': '菜单',
        'value': 1
      }, {
        'label': '目录',
        'value': 0
      }],
      rulesEditMenuDetail: {
        name: [{ required: true, message: '请输入菜单名', trigger: 'change' }],
        path: [{ required: true, message: '请输入菜单路径', trigger: 'change' }],
        component: [{ required: true, message: '请输入组件名称', trigger: 'change' }],
        icon: [{ required: true, message: '请选择图标', trigger: 'change' }]
      },
      rulesEditOrAdd: {
        name: [{ required: true, message: '请输入菜单名', trigger: 'blur' }],
        path: [{ required: true, message: '请输入菜单路径', trigger: 'blur' }],
        component: [{ required: true, message: '请输入组件名称', trigger: 'blur' }],
        icon: [{ required: true, message: '请选择图标', trigger: 'blur' }]
      },
      rulesAddButton: {
        name: [{ required: true, message: '请输入按钮名', trigger: 'blur' }],
        buttonCode: [{ required: true, message: '请输入按钮权限码', trigger: 'blur' }]
      },
      rules: {

      }
    }
  },
  watch: {
    menuDetailData: {
      handler() {
        // 弹窗开启的时候检测的表单由空赋了值，有了一次变动，所以是>1而不是大于0
        this.flagChange++
        if (this.flagChange > 1) {
          this.isChange = true
        }
      },
      deep: true
    },
    filterText(val) {
      this.$refs.tree.filter(val)
    }
  },
  mounted() {
    this.getMenuTree('初始化')
  },
  methods: {
    isMobile,
    menuTypeDict,
    append(data) {
      this.dialogTitle = '新增菜单'
      this.showDialog = true
      if (data !== '' && data.id) {
        this.addOrEditFormData.parentId = data.id
      }
    },
    remove(id, type) {
      MessageBox({
        title: '提示',
        message: '菜单/按钮删除，对应角色拥有的菜单/按钮权限也将被删除，确定删除?'
      }).then(() => {
        deleteById(id)
          .then(res => {
            if (res.success) {
              if (type === '菜单删除') {
                this.getMenuTree('初始化')
              } else {
                this.handleNodeClick(this.nowMenuID)
              }
              this.$message({
                message: '操作成功',
                type: 'success'
              })
            }
          }).catch(err => {
            console.log(err)
          }).finally(() => {
          })
      }).catch(() => {
        this.$message({
          message: '取消操作',
          type: 'info'
        })
      })
    },
    filterNode(value, data) {
      if (!value) return true
      return data.name.indexOf(value) !== -1
    },
    handleNodeClick(id) {
      this.current = 0
      this.editFlag = false
      this.isChange = false
      this.flagChange = 0
      this.nowMenuID = id
      getById(id).then(res => {
        this.menuDetailData = res.data
      }).catch(err => {
        console.log(err)
      }).finally(() => {
      })
      this.getMenuButton(id)
    },
    getMenuTree(type) {
      this.loading = true
      getMenuTree().then(res => {
        this.menuTrees = res.data
        if (type === '初始化') { this.handleNodeClick(res.data[0].id) }
      }).catch(err => {
        console.log(err)
      }).finally(() => {
        this.loading = false
      })
    },
    getMenuButton(pid) {
      this.menuTableLoading = true
      const data = {
        name: this.searchFormData.name,
        buttonCode: this.searchFormData.buttonCode,
        type: '2',
        parentId: pid,
        current: this.current,
        size: this.size
      }
      page(data).then(res => {
        if (res.success) {
          this.tableData = res.data.records
          this.total = res.data.total
        }
      }).catch(err => {
        console.log(err)
      }).finally(() => {
        this.menuTableLoading = false
      })
    },
    editFlagChange() {
      this.editFlag = !this.editFlag
    },
    close() {
      this.showDialog = false
      this.addOrEditFormData = {
        parentId: undefined,
        name: undefined,
        path: undefined,
        component: undefined,
        type: undefined,
        orderNum: 0,
        icon: undefined,
        remark: undefined
      }
      this.$refs['editOrAddForm'].clearValidate()
    },
    buttonClose() {
      this.showButtonDialog = false
      this.addButtonFormData = {
        name: undefined,
        buttonCode: undefined,
        remark: undefined,
        parentId: undefined
      }
    },
    handelConfirm() {
      this.$refs['editOrAddForm'].validate(valid => {
        if (!valid) return
        this.buttonLoading = true
        addMenu(this.addOrEditFormData)
          .then(res => {
            if (res.success) {
              this.getMenuTree()
              this.$message({
                message: '操作成功',
                type: 'success'
              })
            }
          }).catch(err => {
            console.log(err)
          }).finally(() => {
            this.close()
            this.buttonLoading = false
          })
      })
    },
    buttonHandelConfirm() {
      this.$refs['addButtonFormData'].validate(valid => {
        if (!valid) return
        this.buttonLoading = true
        this.addButtonFormData.parentId = this.nowMenuID
        this.addButtonFormData.type = '2'
        addMenu(this.addButtonFormData)
          .then(res => {
            if (res.success) {
              this.handleNodeClick(this.nowMenuID)
              this.$message({
                message: '操作成功',
                type: 'success'
              })
            }
          }).catch(err => {
            console.log(err)
          }).finally(() => {
            this.buttonClose()
            this.buttonLoading = false
          })
      })
    },
    saveMenuDtail() {
      if (!this.editFlag || !this.isChange) {
        this.$message({
          message: '请先编辑',
          type: 'info'
        })
        return
      }
      this.$refs['editMenuDetail'].validate(valid => {
        if (!valid) return
        this.menuLoading = true
        editMenu(this.menuDetailData)
          .then(res => {
            if (res.success) {
              this.handleNodeClick(this.menuDetailData.id)
              this.editFlag = false
              this.getMenuTree()
              this.$message({
                message: '操作成功',
                type: 'success'
              })
            }
          }).catch(err => {
            console.log(err)
          }).finally(() => {
            this.menuLoading = false
          })
      })
    },
    addButton() {
      console.log('按钮添加')
      this.showButtonDialog = true
    },
    handleSizeChange(size) {
      this.size = size
      this.getMenuButton(this.nowMenuID)
    },
    handleCurrentChange(current) {
      this.current = current
      this.getMenuButton(this.nowMenuID)
    },
    searchFlagChange() {
      this.searchFlag = !this.searchFlag
    }
  }
}
</script>

<style scoped>
/deep/ .el-tree > .el-tree-node {
  min-width: 100%;
  display: inline-block;
}
.custom-tree-node {
  flex: 1;
  display: flex;
  align-items: center;
  justify-content: space-between;
  font-size: 14px;
  padding-right: 8px;
}
.table-expand {
  font-size: 0;
}

.table-expand label {
  width: 90px;
  color: #99a9bf;
}

.table-expand .el-form-item {
  margin-right: 0;
  margin-bottom: 0;
  width: 33%;
}
</style>
